﻿// Copyright 2013 Ronald Schlenker and Andre Krämer.
// 
// This file is part of GraphIT.
// 
// GraphIT is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 2 of the License, or
// (at your option) any later version.
// 
// GraphIT is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with GraphIT.  If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Threading;
using System.Windows.Media;
using System.Windows.Threading;
using System.Windows;
using TechNewLogic.GraphIT.MultiLanguage;

namespace TechNewLogic.GraphIT.Printing
{
	/// <summary>
	/// Interaction logic for XpsDocumentGenerator.xaml
	/// </summary>
	partial class RenderWindow : IDisposable
	{
		internal RenderWindow(
			Visual mainPrintContent,
			IViewDrawingState viewDrawingState,
			int width,
			int height,
			int pageMargin)
		{
			_mainPrintContent = mainPrintContent;
			_viewDrawingState = viewDrawingState;
			Width = width;
			Height = height;

			InitializeComponent();

			contentHost.Margin = new Thickness(pageMargin);
			// rescale (see Viewbox) because we are limited to screen res
			contentMargin.Width = width;
			contentMargin.Height = height;
		}

		private readonly Visual _mainPrintContent;
		private readonly IViewDrawingState _viewDrawingState;
		
		private bool _isDisposed;

		internal void Print(Action<Visual> finished)
		{
			contentHost.Content = _mainPrintContent;

			if (!IsLoaded)
			{
				Loaded += (s, e) => DoStartPrint(finished);
				ShowDialog();
			}
			else
				DoStartPrint(finished);
		}

		// IMP: Error Handling -> Event muss auch kommen, wenn es einen Print Error gab
		private void DoStartPrint(Action<Visual> finished)
		{
			ThreadPool.QueueUserWorkItem(o =>
				_viewDrawingState.EnsureViewUpToDate(
					() => _mainPrintContent.Dispatcher.Invoke(() => Finish(finished, _mainPrintContent)),
					() => _mainPrintContent.Dispatcher.Invoke(() =>
						{
							var document = TextDocumentGenerator.CreateControl(
								(int)Width,
								(int)Height,
								MlResources.CannotCreateDocument);
							Finish(finished, document);
						}),
					TimeSpan.FromSeconds(30)));
		}

		private void Finish(Action<Visual> finished, Visual visual)
		{
			if (_isDisposed)
				return;

			contentHost.Content = null;
			Close();

			Dispatcher.Invoke(() => finished(visual));
		}

		public void Dispose()
		{
			_isDisposed = true;

			contentHost.Content = null;
			Close();
		}
	}
}
